package ginserver

import (
	"go-base/internal/services/auth"
	"net/http"
	"net/url"
	"strings"

	"github.com/gin-gonic/gin"
)

// allowCORSMiddleware 忽略跨域中间件，允许所有跨域请求
func allowCORSMiddleware(router *gin.Engine) {
	// 忽略跨域中间件，允许所有跨域请求
	router.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
		c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Next()
	})
}

// forceHttpsMiddleware 强制要求使用HTTPS的中间件
func forceHttpsMiddleware(router *gin.Engine) {
	// 强制要求使用HTTPS的中间件
	router.Use(func(c *gin.Context) {
		if c.Request.TLS == nil {
			c.AbortWithStatus(http.StatusMovedPermanently)
		}
	})
}

// noRouterResponseMiddleware 配置统一处理无路由的情况
func noRouterResponseMiddleware(router *gin.Engine) {
	// 配置统一处理无路由的情况
	router.NoRoute(func(c *gin.Context) {
		c.JSON(http.StatusNotFound, gin.H{"code": http.StatusNotFound, "message": "Error", "data": "Page not found"})
	})
}

// CustomLogMiddleware 创建一个自定义的日志中间件
func CustomLogMiddleware(notLoggedRoutes []routeInfo) gin.HandlerFunc {
	return func(c *gin.Context) {
		path := c.Request.URL.Path
		method := c.Request.Method
		for _, route := range notLoggedRoutes {
			if route.Path == path && route.Method == method {
				// 如果当前路径和方法与notLoggedRoutes中的某个相匹配，不记录日志
				c.Next()
				return
			}
		}
		// 使用Gin的Logger中间件
		gin.Logger()(c)
	}
}

// AuthMiddleware 中间件函数，用于验证 token
func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		if strings.Contains(c.Request.URL.Path, "/swagger/") {
			c.Next()
			return
		}

		// 打印所有 header 信息
		//for k, v := range c.Request.Header {
		//	fmt.Printf("Header [%s] -> %v\n", k, v)
		//}

		token := c.GetHeader("Authorization")
		if token == "" {
			c.JSON(http.StatusUnauthorized, HttpResponse{
				Code:    401,
				Message: "验证失败",
				Data:    "Token不能为空",
			})
			c.Abort()
			return
		}

		if !auth.TokenIsEffective(token) {
			c.JSON(http.StatusUnauthorized, HttpResponse{
				Code:    401,
				Message: "验证失败",
				Data:    "Token失效",
			})
			c.Abort()
			return
		}

		c.Next()
	}
}

// NormalizeParamsMiddleware 统一参数和路径参数的获取
func NormalizeParamsMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 创建一个 map 来存储统一的路径参数
		normalizedParams := make(map[string]string)

		// 遍历现有的路径参数
		for _, param := range c.Params {
			normalizedParams[strings.ToLower(param.Key)] = param.Value
		}

		// 覆盖原有的路径参数获取方法
		c.Params = c.Params[:0]
		for key, value := range normalizedParams {
			c.Params = append(c.Params, gin.Param{Key: key, Value: value})
		}

		// 创建一个 map 来存储统一的查询参数
		normalizedQuery := make(map[string]string)

		// 遍历现有的查询参数
		for key, values := range c.Request.URL.Query() {
			normalizedQuery[strings.ToLower(key)] = values[0]
		}

		// 构建新的查询字符串
		var newQueryString string
		for key, value := range normalizedQuery {
			if newQueryString != "" {
				newQueryString += "&"
			}
			newQueryString += url.QueryEscape(key) + "=" + url.QueryEscape(value)
		}

		// 更新查询字符串
		c.Request.URL.RawQuery = newQueryString

		// 继续处理请求
		c.Next()
	}
}
